package com.rent.weixin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.rent.common.utils.StringUtils;
import com.rent.weixin.api.WxConstants;
import com.rent.weixin.datasource.AccessTokenCache;
import com.rent.weixin.model.WxAccessToken;
import com.rent.weixin.service.IWxAccessTokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @Author zhang
 * @create 2021/8/9 11:51
 */
@Slf4j
@Service
public class WxAccessTokenService implements IWxAccessTokenService {


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;

//    @Autowired
//    private WeixinPublicConfigFeign configService;
    /**
     * token 锁
     */
    private Lock lock = new ReentrantLock();

    @Override
    public String getWxAccessToken(String appid) {
        appid = StringUtils.trim(appid);
        log.info("获取微信token的appid" + appid);
        if (StringUtils.isEmpty(appid)) return null;
        WxAccessToken wxAccessToken = AccessTokenCache.INSTANCE.get(appid);
        // 如果token未过期返回
        if (wxAccessToken != null && !wxAccessToken.isExpired()) {
            return wxAccessToken.getAccess_token();
        }
        // 移除缓存中的token
        AccessTokenCache.INSTANCE.remove(appid);
        try {
            lock.lock();
            // 把token压入本地缓存中
            // 先获取公众号配置数据
//            String objectStr = redisTemplate.opsForValue().get("Appid_" + appid);
//            WeixinPublicConfig config;
//            if (StringUtils.isEmpty(objectStr)) {
//                config = configService.getConfigByAppid(appid);
//                if (config == null) return null;
//                //4.数据添加到redis中  key:用户openid 值微信token
//                redisTemplate.opsForValue().set("Appid_" + appid, JSON.toJSONString(config));
//            } else {
//                config = JSON.parseObject(objectStr, WeixinPublicConfig.class);
//            }
//            if (config == null) return null;
//            String secret = "&secret=" + config.getSecret();
            String secret = "&secret=" + "";
            String url = WxConstants.GET_ACCESS_TOKEN_URL + appid + secret;
            log.info("微信Token请求:" + url);
            String response = restTemplate.getForObject(url, String.class);
            log.info("微信token请求结果:" + response);
            if (response == null || response.contains("errcode")) {
                return null;
            }
            JSONObject jsonObject = JSONObject.parseObject(response);
            WxAccessToken accessToken = new WxAccessToken();
            accessToken.setAccess_token(jsonObject.get("access_token").toString());
            String in = jsonObject.get("expires_in").toString();
            accessToken.setExpires_in(Long.parseLong(in));
            AccessTokenCache.INSTANCE.add(appid, accessToken);
            return accessToken.getAccess_token();
        } catch (Exception e) {
            log.info("解析异常:{}", e.getMessage());
        } finally {
            lock.unlock();
        }
        return null;
    }


    /**
     * jsapi_ticket是公众号用于调用微信JS接口的临时票据
     */
    public String getJsApiTicket(String accessToken, String type, String appid) {
        // 先获取ticket
        String ticket = redisTemplate.opsForValue().get("JSAPITICKET_" + appid);
        if (!StringUtils.isEmpty(ticket)) {
            ticket = StringUtils.trim(ticket);
            return ticket;
        }
        String jsApiTicket = "";
        // 这个url链接地址和参数皆不能变
        String url = WxConstants.GET_WX_API_TICKET + accessToken + "&type=" + type;
        try {
            log.info("微信jsApitecket请求:" + url);
            String response = restTemplate.getForObject(url, String.class);
            if (StringUtils.isEmpty(response)) return jsApiTicket;
            JSONObject jsonObject = JSONObject.parseObject(response);
            if (jsonObject == null) return null;
            log.info("获取jsapi_ticket返回的json:" + jsonObject);
            Long expiresIn = jsonObject.getLong("expires_in");
            String apiTicket = jsonObject.getString("ticket");
            if (StringUtils.isEmpty(apiTicket)) return null;
            apiTicket = StringUtils.trim(apiTicket);
            if (StringUtils.isEmpty(apiTicket)) return null;
            jsApiTicket = StringUtils.trim(apiTicket);
            //4.数据添加到redis中  key:用户openid 值微信token
            redisTemplate.opsForValue().set("JSAPITICKET_" + appid, jsApiTicket, expiresIn, TimeUnit.SECONDS);
        } catch (Exception e) {
            log.debug("获取jsapi_ticket发生异常", e);
        }
        return jsApiTicket;
    }


    @Override
    public void updateWxAccessToken(String appid) {
        appid = StringUtils.trim(appid);
        if (StringUtils.isEmpty(appid)) return;
        WxAccessToken wxAccessToken = AccessTokenCache.INSTANCE.get(appid);
        if (wxAccessToken == null) {
            wxAccessToken = new WxAccessToken();
        }
        try {
            lock.lock();
            // 把token压入本地缓存中
            // 先获取公众号配置数据
//            String objectStr = redisTemplate.opsForValue().get("Appid_" + appid);
//            WeixinPublicConfig config;
//            if (StringUtils.isEmpty(objectStr)) {
//                config = configService.getConfigByAppid(appid);
//                if (config == null) return;
//                //4.数据添加到redis中  key:用户openid 值微信token
//                redisTemplate.opsForValue().set("Appid_" + appid, JSON.toJSONString(config));
//            } else {
//                config = JSON.parseObject(objectStr, WeixinPublicConfig.class);
//            }
//            if (config == null) return;
//            String secret = "&secret=" + config.getSecret();
            String secret = "&secret=" + "config.getSecret()";
            String url = WxConstants.GET_ACCESS_TOKEN_URL + appid + secret;
            log.info("微信Token请求:" + url);
            String response = restTemplate.getForObject(url, String.class);
            if (response == null || response.contains("errcode")) {
                return;
            }
            JSONObject jsonObject = JSONObject.parseObject(response);
            String token = jsonObject.get("access_token").toString();
            String in = jsonObject.get("expires_in").toString();
            long exin = Long.parseLong(in);
            wxAccessToken.updateAccessToken(token, exin);
            AccessTokenCache.INSTANCE.add(appid, wxAccessToken);
        } catch (Exception e) {
            log.info("解析异常:{}", e.getMessage());
        } finally {
            lock.unlock();
        }
    }

}
